package com.webvihar.common.utils;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URI;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;

/**
 * @author Viswanath Kumar Sandu
 * 
 */
public abstract class AbstractHttpHelper {
	protected abstract void setupRequest(HttpRequestBase request);
	protected abstract DefaultHttpClient createHttpClient();
	
	public HttpResult getString(String url) {
		Logger.logInfo(Logger.LOG_TAG, String.format("%s  HTTP type is: GET  ", this.getClass().getName()));
		return doRequest(new HttpGet(), url);
	}

	public HttpResult putString(String url) {
		Logger.logInfo(Logger.LOG_TAG, String.format("%s  HTTP type is: PUT  ", this.getClass().getName()));
		return doRequest(new HttpPut(), url);
	}

	public HttpResult deleteString(String url) {
		Logger.logInfo(Logger.LOG_TAG, String.format("%s  HTTP type is: DELETE  ", this.getClass().getName()));
		return doRequest(new HttpDelete(), url);
	}

	public HttpResult postString(String url, String data) {
		Logger.logInfo(Logger.LOG_TAG, String.format("%s  HTTP type is: POST  ", this.getClass().getName()));
		HttpPost postRequest = new HttpPost();
		try {
			if(data != null) postRequest.setEntity(new StringEntity(data));
		}
		catch (UnsupportedEncodingException e) {
			Logger.logError(Logger.LOG_TAG, String.format("%s  UnsupportedEncodingException: postString(): Error occurred.  ", this.getClass().getName()), e);
			e.printStackTrace();
		}		
		return doRequest(postRequest, url);
	}
	
	private HttpResult doRequest(HttpRequestBase request, String url) {
		HttpResult httpResult = null;
		DefaultHttpClient client = createHttpClient();
		try {
			Logger.logInfo(Logger.LOG_TAG, String.format("%s  URL is = %s  ", this.getClass().getName(), url));
			request.setURI(URI.create(url.trim()));
			setupRequest(request);
			httpResult = getHttpResult(client.execute(request));
			Logger.logInfo(Logger.LOG_TAG, String.format("%s  doRequest(): Status code from server is = %s  ", this.getClass().getName(), String.valueOf(httpResult.statusCode)));
			Logger.logInfo(Logger.LOG_TAG, String.format("%s  doRequest(): Response from server is = %s  ", this.getClass().getName(), httpResult.result));
			client.getConnectionManager().shutdown();
		}
		catch (ClientProtocolException e) {
			Logger.logError(Logger.LOG_TAG, String.format("%s  ClientProtocolException: doRequest(): Error occurred while contacting server.  ", this.getClass().getName()), e);
			client.getConnectionManager().shutdown();
		}
		catch (IOException e) {
			Logger.logError(Logger.LOG_TAG, String.format("%s  IOException: doRequest(): Error occurred while contacting server.  ", this.getClass().getName()), e);
			client.getConnectionManager().shutdown();
		}
		catch (Exception e) {
			Logger.logError(Logger.LOG_TAG, String.format("%s  Exception: doRequest(): Error occurred while contacting server.  ", this.getClass().getName()), e);
			client.getConnectionManager().shutdown();
		}
		return httpResult;
	}

	private HttpResult getHttpResult(HttpResponse httpResponse) throws ParseException, IOException {
		String responseMessage = null;
		HttpEntity httpEntity = httpResponse.getEntity();
		if (httpEntity != null) responseMessage = EntityUtils.toString(httpEntity);
		HttpResult httpResult = new HttpResult();
		httpResult.result = responseMessage;
		int statusCode = httpResponse.getStatusLine() == null ? 0 : httpResponse.getStatusLine().getStatusCode();
		httpResult.statusCode = statusCode;
		return httpResult;
	}
}
